package com.smartlock;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.*;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.smartlock.param.ApiResult;
import com.smartlock.param.RemoteUnLockParam;
import com.smartlock.service.RemoteUnLockService;
import com.smartlock.util.BytesUtils;

@Controller
@RequestMapping("/lock")
public class RemoteUnLockController {

    private static ExecutorService executorService = Executors.newFixedThreadPool(3);
    private Logger                 logger          = LoggerFactory.getLogger(RemoteUnLockController.class);

    //    @ResponseBody
    //    @RequestMapping("/remoteUnLock")
    //    public ApiResult<Boolean> unLock(@RequestBody RemoteUnLockParam param) throws IOException, InterruptedException {
    //        logger.info("接收到远程开锁请求：" + JSON.toJSONString(param));
    //        if (StringUtils.isBlank(param.getLockMac())) {
    //            throw new IllegalArgumentException(param.getLockMac());
    //        }
    //        byte[] command = RemoteUnLockService.remoteUnlock(param);
    //        Socket socket = takeSocket(param.getLockMac());
    //        if (socket == null) {
    //            logger.error("远程开锁失败，无法获取智能锁连接！lockMac=" + param.getLockMac());
    //            return ApiResult.fail(Boolean.FALSE, "远程开锁失败，无法获取智能锁连接！");
    //        }
    //        OutputStream out = socket.getOutputStream();
    //        out.write(command);
    //        out.flush();
    //        logger.info("发送开锁指令lockMac:" + param.getLockMac() + ",指令内容为：" + BytesUtils.formatHexString(command));
    //        return ApiResult.ok(Boolean.TRUE, "远程开锁指令发送成功！");
    //    }

    @ResponseBody
    @RequestMapping("/remoteUnLock1")
    public ApiResult<Boolean> unLock1(RemoteUnLockParam param) {
        logger.info("接收到远程开锁请求：" + JSON.toJSONString(param));
        if (StringUtils.isBlank(param.getLockMac())) {
            throw new IllegalArgumentException("锁mac地址不能为空，lockMac=" + param.getLockMac());
        }
        if (StringUtils.isBlank(param.getGatewayMac())) {
            throw new IllegalArgumentException("网关mac地址不能为空，gateway=" + param.getGatewayMac());
        }
        if (StringUtils.isBlank(param.getLockPwd())) {
            throw new IllegalArgumentException("管理密码不能为空，pwd=" + param.getLockPwd());
        }
        String[] lockPwds = StringUtils.split(param.getLockPwd(), ",");
        if (lockPwds.length <= 0 || lockPwds.length > 12) {
            throw new IllegalArgumentException("管理密码长度不正确，pwd=" + param.getLockPwd());
        }
        byte[] command = RemoteUnLockService.remoteUnlock(param);
        Socket socket = takeSocket(param.getGatewayMac());
        if (socket == null) {
            logger.error("远程开锁失败，无法获取智能锁连接！gatewayMac=" + param.getGatewayMac());
            return ApiResult.fail(Boolean.FALSE, "远程开锁失败，无法获取智能锁连接！");
        }
        try {
            OutputStream out = socket.getOutputStream();
            out.write(command);
            out.flush();
        } catch (IOException e) {
            logger.error("获取到已中断的连接！gatewayMac=" + param.getGatewayMac(), e);
            return ApiResult.fail(Boolean.FALSE, "远程开锁失败，无法获取智能锁连接！");
        }
        logger.info("gatewayMac:" + param.getGatewayMac() + ",指令内容为：" + BytesUtils.formatHexString(command));
        return ApiResult.ok(Boolean.TRUE, "远程开锁指令发送成功！");
    }

    private Socket takeSocket(String gatewayMac) {
        Callable<Socket> socketCallable = () -> {
            Socket socket = null;
            while (socket == null) {
                socket = Main.getMacSocketMap().get(gatewayMac);
            }
            return socket;
        };
        Future socketFuture = executorService.submit(socketCallable);
        try {
            return (Socket) socketFuture.get(10l, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            logger.error("获取锁连接异常：", e);
        } catch (ExecutionException e) {
            logger.error("获取锁连接异常：", e);
        } catch (TimeoutException e) {
            logger.error("获取锁连接超时，网关mac=" + gatewayMac, e);
        }
        return null;
    }
}
